package com.ruoyi.quartz.task;


import com.ruoyi.quartz.dto.RoadManageVo;
import com.snowRemovingUser.domain.*;
import com.snowRemovingUser.mapper.TCommentRiskLevelRuleMapper;
import com.snowRemovingUser.mapper.THsoIndexAllMapper;
import com.snowRemovingUser.mapper.THsoIndexLastMapper;
import com.snowRemovingUser.mapper.TSeasonMapper;
import com.snowRemovingUser.service.ITPredictionAllService;
import com.snowRemovingUser.service.ITPredictionService;
import com.snowRemovingUser.service.ITRoadManageService;
import com.snowRemovingUser.service.ITWeatherSynopsisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.DecimalFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 * 自动更新自动化报表
 */
@Component("automatedReportTask")
public class AutomatedReportTask {

    /** log */
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private THsoIndexLastMapper hsoIndexLastMapper;

    @Autowired
    private TSeasonMapper tSeasonMapper;


    @Autowired
    private THsoIndexAllMapper hsoIndexAllMapper;


    @Autowired
    private TCommentRiskLevelRuleMapper commentRiskLevelRuleMapper;


    @Autowired
    private ITWeatherSynopsisService weatherSynopsisService;

    @Autowired
    private ITRoadManageService roadManageService;

    @Autowired
    private ITPredictionService predictionService;

    @Autowired
    private ITPredictionAllService predictionAllService;




    public void start(){

        // 查询需要生成预报数据的路段
        TRoadManage tRoadManage = new TRoadManage();
        tRoadManage.setStatus("1");

        List<TRoadManage> tRoadManages = roadManageService.selectTRoadManageList(tRoadManage);


        List<RoadManageVo> roadManageVos = new ArrayList<>();

        for (TRoadManage roadManage : tRoadManages) {

            RoadManageVo roadManageVo = new RoadManageVo();
            BeanUtils.copyProperties(roadManage, roadManageVo);
            roadManageVos.add(roadManageVo);
        }

        Map<Long, RoadManageVo> roadManageMap = roadManageVos.stream()
                .collect(Collectors.toMap(RoadManageVo::getId, Function.identity()));

        List<RoadManageVo> roadManageTree = new ArrayList<>();

        //遍历所有行业
        for (RoadManageVo roadManageVo : roadManageVos) {

            if (roadManageVo.getParentId()==0){

                // 如果是最上级 就添加到 roadManageTree
                roadManageTree.add(roadManageVo);
            }else {


                //不是最上级 就添加到上级的children中
                RoadManageVo parent = roadManageMap.get(roadManageVo.getParentId());
                parent.getChildren().add(roadManageVo);
            }
        }

        // 1级路段
        for (RoadManageVo roadManageVo : roadManageTree) {

            // 2级路段
            List<RoadManageVo> roadManageVos2 = roadManageVo.getChildren();

            THsoIndexLast tHsoIndexLast1 = new THsoIndexLast();
            Map<String, Object> ftMap1 = new HashMap<>();
            ftMap1.put("ftMin",1);
            ftMap1.put("ftMax",24);
            tHsoIndexLast1.setParams(ftMap1);
            tHsoIndexLast1.setPlaceName(roadManageVos2.get(0).getPlace());
            List<THsoIndexLast> tHsoIndexLasts = hsoIndexLastMapper.selectTHsoIndexLastList(tHsoIndexLast1);
            if (tHsoIndexLasts.size()>0){
                // 检查数据是否是最新数据
                TPrediction prediction = new TPrediction();
                prediction.setAnnounceTime(tHsoIndexLasts.get(0).getAnnounceTime());
                List<TPrediction> tPredictions = predictionService.selectTPredictionList(prediction);
                if (tPredictions.size()>0){
                    logger.info("已是最新数据，无需重复更新");
                    break;
                }
            }

            // 如果不是最新数据 把老数据放入到历史表中 然后再添加新数据
            TPrediction tPrediction1 = new TPrediction();
            List<TPrediction> tPredictions = predictionService.selectTPredictionList(tPrediction1);

            for (TPrediction tPrediction : tPredictions) {

                TPredictionAll tPredictionAll = new TPredictionAll();
                BeanUtils.copyProperties(tPrediction,tPredictionAll);
                predictionAllService.insertTPredictionAll(tPredictionAll);
                predictionService.deleteTPredictionById(tPrediction.getId());
            }


            // 数据封装
            for (RoadManageVo roadmanageVo : roadManageVos2) {


                THsoIndexLast tHsoIndexLast = new THsoIndexLast();
                Map<String, Object> ftMap = new HashMap<>();
                ftMap.put("ftMin",1);
                ftMap.put("ftMax",24);
                tHsoIndexLast.setParams(ftMap);
                tHsoIndexLast.setPlaceName(roadmanageVo.getPlace());
                List<THsoIndexLast> roadList = hsoIndexLastMapper.selectTHsoIndexLastList(tHsoIndexLast);
                List<THsoIndexLast> refinementDataList = new ArrayList<>(roadList);


                // 24小时气象概要
                String comment = summarySplicing(roadList, roadManageVo.getPlace());



                ftMap.put("ftMin",1);
                ftMap.put("ftMax",72);
                tHsoIndexLast.setParams(ftMap);
                tHsoIndexLast.setPlaceName(roadmanageVo.getPlace());
                List<THsoIndexLast> road1_72hList = hsoIndexLastMapper.selectTHsoIndexLastList(tHsoIndexLast);
                // 未来三天概要
                String predictionComment = futureWeatherSynopsis(road1_72hList);

                //数据插入
                TPrediction tPrediction = new TPrediction();
                tPrediction.setAnnounceTime(roadList.get(0).getAnnounceTime());
                tPrediction.setLocalTime(roadList.get(0).getLocalTime());
                tPrediction.setPlaceName(roadmanageVo.getPlace());
                tPrediction.setComment(comment);
                tPrediction.setPredictionComment(predictionComment);
                tPrediction.setPredictionStatus(0);
                tPrediction.setParentId(0L);
                tPrediction.setUpdateTime(new Date());
                predictionService.insertTPrediction(tPrediction);



                //表格数据封装
                ftMap.put("ftMin",1);
                ftMap.put("ftMax",24);
                tHsoIndexLast.setParams(ftMap);
                tHsoIndexLast.setPlaceName(roadmanageVo.getPlace());
                List<THsoIndexLast> road1_24hList = hsoIndexLastMapper.selectTHsoIndexLastList(tHsoIndexLast);
                for (THsoIndexLast hsoIndexLast : road1_24hList) {

                    TPrediction tPredictionTable = new TPrediction();
                    tPredictionTable.setAnnounceTime(hsoIndexLast.getAnnounceTime());
                    tPredictionTable.setLocalTime(hsoIndexLast.getLocalTime());
                    tPredictionTable.setPlaceName(hsoIndexLast.getPlaceName());
                    tPredictionTable.setFt(hsoIndexLast.getFt());
                    // 降雪量
                    if (hsoIndexLast.getSnow() != null && !hsoIndexLast.getSnow().equals("0") && !hsoIndexLast.getSnow().equals("0.0") && !hsoIndexLast.getSnow().equals("")){

                        tPredictionTable.setSnow(hsoIndexLast.getSnow());
                    }else {
                        tPredictionTable.setSnow("0");
                    }
                    // 降雨量
                    if (hsoIndexLast.getRain() != null && !hsoIndexLast.getRain().equals("0") && !hsoIndexLast.getRain().equals("0.0") && !hsoIndexLast.getRain().equals("")){

                        tPredictionTable.setRain(hsoIndexLast.getRain());
                    }else {
                        tPredictionTable.setRain("0");
                    }


                    tPredictionTable.setParentId(tPrediction.getId());
                    tPredictionTable.setUpdateTime(new Date());
                    predictionService.insertTPrediction(tPredictionTable);
                }


                // 封装 路段下桩号的表格数据
                List<RoadManageVo> landMarkList = roadmanageVo.getChildren();

                for (RoadManageVo landMark : landMarkList) {

                    tHsoIndexLast.setPlaceName(landMark.getPlace());
                    List<THsoIndexLast> landMark_24hList = hsoIndexLastMapper.selectTHsoIndexLastList(tHsoIndexLast);
                    refinementDataList.addAll(landMark_24hList);

                    for (THsoIndexLast hsoIndexLast : landMark_24hList) {

                        TPrediction tPredictionTable = new TPrediction();
                        tPredictionTable.setAnnounceTime(hsoIndexLast.getAnnounceTime());
                        tPredictionTable.setLocalTime(hsoIndexLast.getLocalTime());
                        tPredictionTable.setPlaceName(hsoIndexLast.getPlaceName());
                        tPredictionTable.setFt(hsoIndexLast.getFt());
                        tPredictionTable.setAirtmp(hsoIndexLast.getAirtmp());
                        tPredictionTable.setParentId(tPrediction.getId());
                        tPredictionTable.setUpdateTime(new Date());
                        predictionService.insertTPrediction(tPredictionTable);
                    }
                }


                // 精细化预报拼接
                String weatherExplain = refinementWeatherSynopsis(tPrediction.getId(),roadManageVo.getPlace());
                tPrediction.setWeatherExplain(weatherExplain);
                predictionService.updateTPrediction(tPrediction);
            }

            logger.info("数据插入成功");
        }

    }


    /**
     * 24小时气象概要拼接
     * @param roadHsoIndexLasts
     * @param road
     * @return
     */
    private String summarySplicing(List<THsoIndexLast> roadHsoIndexLasts,String road){

        // 未来24小时气象概要
        StringBuilder comment = new StringBuilder();

        // 1.季节
        String season = null;
        LocalDateTime now = LocalDateTime.now();
        int monthValue = now.getMonthValue();
        List<TSeason> tSeasons = tSeasonMapper.selectTSeasonList(new TSeason());


        // 判断当前月份
        for (TSeason tSeason : tSeasons) {

            // 暖侯期
            if (tSeason.getName().contains("冰")){

                if (monthValue>=tSeason.getMonthMin() || monthValue<=tSeason.getMonthMax()){
                    season = tSeason.getName();
                    break;
                }

                // 冰雪期
            }else {

                if (monthValue>=tSeason.getMonthMin() && monthValue<=tSeason.getMonthMax()){
                    season = tSeason.getName();
                    break;
                }
            }
        }

        // 提取事件
        List<THsoIndexLast> valList = new ArrayList<>();
        String txt = null;

        int a = 0;
        assert season != null;
        if (season.equals("暖侯期")){

            // 降雨判断
            for (THsoIndexLast hsoIndexLast : roadHsoIndexLasts) {
                String rain = hsoIndexLast.getRain();
                if (rain != null && !rain.equals("0") && !rain.equals("0.0") && !rain.equals("")) {
                    valList.add(hsoIndexLast);
                    a = 1;
                } else {
                    if (a == 1) {
                        break;
                    }
                }
            }

            // 降雨
            if (valList.size()>0){

                txt = rainSynopsis(roadHsoIndexLasts, road, valList);
                // 无降雨
            }else {

                TWeatherSynopsis tWeatherSynopsis = new TWeatherSynopsis();
                tWeatherSynopsis.setCommentType("无降雨");
                List<TWeatherSynopsis> tWeatherSynopses = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis);
                TWeatherSynopsis tWeatherSynopsis1 = tWeatherSynopses.get(0);
                txt = tWeatherSynopsis1.getRiskDescription() + "，" + tWeatherSynopsis1.getProposeMeasure();

            }

            // 冬季
        }else {


            // 降雪
            for (THsoIndexLast hsoIndexLast : roadHsoIndexLasts) {
                String snow = hsoIndexLast.getSnow();
                if (snow != null && !snow.equals("0") && !snow.equals("0.0")) {
                    valList.add(hsoIndexLast);
                    a = 1;
                } else {
                    if (a == 1) {
                        break;
                    }
                }
            }

            // 有降雪
            if (valList.size()>0){

                txt = snowSynopsis(roadHsoIndexLasts, road, valList);

                // 无降雪判断 是否有降雨
            }else {

                // 降雨判断
                for (THsoIndexLast hsoIndexLast : roadHsoIndexLasts) {
                    String rain = hsoIndexLast.getRain();
                    if (rain != null && !rain.equals("0") && !rain.equals("0.0")) {
                        valList.add(hsoIndexLast);
                        a = 1;
                    } else {
                        if (a == 1) {
                            break;
                        }
                    }
                }

                // 有降雨
                if (valList.size()>0){

                    txt = rainSynopsis(roadHsoIndexLasts, road, valList);

                    //  无降雨则判断是否结冰
                }else {


                }
            }
        }



        comment.append(txt);
        return comment.toString();
    }




    /**
     *  降雨 24小时概要
     * @param roadHsoIndexLasts 未来24小时数据
     * @param road 路段
     * @param valList
     * @return
     */
    private String rainSynopsis(List<THsoIndexLast> roadHsoIndexLasts, String road, List<THsoIndexLast> valList) {


        String txt = null;
        // 当前推送时间
        Date localTime = roadHsoIndexLasts.get(0).getLocalTime();

        // 获取事件 发送时间
        String timeStr;
        Long ft = valList.get(0).getFt();
        long localTimeInMillis = localTime.getTime();
        long newTimeInMillis = localTimeInMillis + (ft * 60 * 60 * 1000);
        Date evenStartTime = new Date(newTimeInMillis);
        int hours = evenStartTime.getHours();
        String[] timePeriods = {
                "下半夜", "下半夜", "下半夜", "下半夜","下半夜", "早晨",
                "早晨", "早晨", "上午", "上午", "上午", "中午","中午",
                "下午", "下午", "下午","下午", "傍晚", "傍晚","傍晚",
                "上半夜","上半夜","上半夜", "上半夜"
        };
        timeStr = timePeriods[hours];


        // 未来1天下雨总和
        double RainSum = roadHsoIndexLasts.stream().mapToDouble(hsoIndexLast -> { String rain = hsoIndexLast.getRain(); if (rain == null || rain.isEmpty()) { return 0.0; } else { return Double.parseDouble(rain); } }).sum();

        // 创建一个Calendar对象，并设置为localTime的日期时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(localTime);

        // 推移1天
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        // 获取推移后的日期时间
        Date pass1day = calendar.getTime();

        // 推移3天
        calendar.add(Calendar.DAY_OF_MONTH, -2);
        // 获取推移后的日期时间
        Date pass2day = calendar.getTime();

        // 推移3天
        calendar.add(Calendar.DAY_OF_MONTH, -3);
        // 获取推移后的日期时间
        Date pass3day = calendar.getTime();


        THsoIndexAll tHsoIndexAll = new THsoIndexAll();
        Map<String, Object> ftMap = new HashMap<>();
        ftMap.put("ftMin",1);
        ftMap.put("ftMax",24);
        tHsoIndexAll.setParams(ftMap);
        tHsoIndexAll.setPlaceName(roadHsoIndexLasts.get(0).getPlaceName());

        // 查询过去1天的降雨情况
        tHsoIndexAll.setLocalTime(pass1day);
        List<THsoIndexAll> tHsoIndex1days = hsoIndexAllMapper.selectTHsoIndexAllList(tHsoIndexAll);
        double RainSum1Day = tHsoIndex1days.stream().mapToDouble(hsoIndexAll -> { String rain = hsoIndexAll.getRain(); if (rain == null || rain.isEmpty()) { return 0.0; } else { return Double.parseDouble(rain); } }).sum();

        // 查询过去2天的降雨情况
        tHsoIndexAll.setLocalTime(pass2day);
        List<THsoIndexAll> tHsoIndex2days = hsoIndexAllMapper.selectTHsoIndexAllList(tHsoIndexAll);
        double RainSum2Day = tHsoIndex2days.stream().mapToDouble(hsoIndexAll -> { String rain = hsoIndexAll.getRain(); if (rain == null || rain.isEmpty()) { return 0.0; } else { return Double.parseDouble(rain); } }).sum();

        // 查询过去3天的降雨情况
        tHsoIndexAll.setLocalTime(pass3day);
        List<THsoIndexAll> tHsoIndex3days = hsoIndexAllMapper.selectTHsoIndexAllList(tHsoIndexAll);
        double RainSum3Day = tHsoIndex3days.stream().mapToDouble(hsoIndexAll -> { String rain = hsoIndexAll.getRain(); if (rain == null || rain.isEmpty()) { return 0.0; } else { return Double.parseDouble(rain); } }).sum();


        // 查询过去14天的降雨情况
        Map<String, Object> Pass14DayMap = new HashMap<>();
        List<Date> pastDates = new ArrayList<>();

        for (int i = 1; i <= 14; i++) {
            LocalDateTime localDateTime = localTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().minusDays(i);
            Date pastDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
            pastDates.add(pastDate);
        }


        Pass14DayMap.put("ftMin",1);
        Pass14DayMap.put("ftMax",24);
        Pass14DayMap.put("localTimes", pastDates);
        Pass14DayMap.put("placeName", roadHsoIndexLasts.get(0).getPlaceName());
        List<THsoIndexAll> tHsoIndex14days = hsoIndexAllMapper.selectTHsoIndexAllListByLocalTime(Pass14DayMap);
        double RainSum14Day = tHsoIndex14days.stream().mapToDouble(hsoIndexAll -> { String rain = hsoIndexAll.getRain(); if (rain == null || rain.isEmpty()) { return 0.0; } else { return Double.parseDouble(rain); } }).sum();

        // 判断分级规则

        TWeatherSynopsis tWeatherSynopsis2 = new TWeatherSynopsis();
        tWeatherSynopsis2.setCommentType("连续降雨");
        tWeatherSynopsis2.setRoad(road);
        List<TWeatherSynopsis> tWeatherSynopses1 = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis2);


        // 查询连续降雨触发条件
        TCommentRiskLevelRule tCommentRiskLevelRule = new TCommentRiskLevelRule();
        tCommentRiskLevelRule.setRiskType("12");
        tCommentRiskLevelRule.setRiskLevel("3");
        tCommentRiskLevelRule.setRiskLevelRuleId(tWeatherSynopses1.get(0).getRiskRuleId());
        List<TCommentRiskLevelRule> tCommentRiskLevelRules1 = commentRiskLevelRuleMapper.selectTCommentRiskLevelRuleList(tCommentRiskLevelRule);

        // 过去14天满足条件
        int RainSum14DayRule = Integer.parseInt(Objects.requireNonNull(tCommentRiskLevelRules1.stream().filter(commentRiskLevelRule -> commentRiskLevelRule.getRuleNo() == 1).findFirst().orElse(null)).getMinValue());

        // 过去3天满足条件
        int RainSum3DayRule = Integer.parseInt(Objects.requireNonNull(tCommentRiskLevelRules1.stream().filter(commentRiskLevelRule -> commentRiskLevelRule.getRuleNo() == 2).findFirst().orElse(null)).getMinValue());

        // 基本条件满足条件
        int basicRule = Integer.parseInt(Objects.requireNonNull(tCommentRiskLevelRules1.stream().filter(commentRiskLevelRule -> commentRiskLevelRule.getRuleNo() == 3).findFirst().orElse(null)).getMinValue());

        // 连续降雨
        if (RainSum> basicRule && (RainSum1Day>RainSum3DayRule || RainSum2Day>RainSum3DayRule || RainSum3Day>RainSum3DayRule) && RainSum14Day>RainSum14DayRule){

            TWeatherSynopsis tWeatherSynopsis = new TWeatherSynopsis();
            tWeatherSynopsis.setCommentType("连续降雨");
            List<TWeatherSynopsis> tWeatherSynopses = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis);
            TWeatherSynopsis tWeatherSynopsis1 = tWeatherSynopses.get(0);
            txt = tWeatherSynopsis1.getRiskDescription() + "，" + tWeatherSynopsis1.getTrafficImpact();

            // 普通降雨
        }else {

            // 24小时雅西降雨规则
            TCommentRiskLevelRule commentRiskLevelRule = new TCommentRiskLevelRule();

            TWeatherSynopsis tWeatherSynopsis3 = new TWeatherSynopsis();
            tWeatherSynopsis3.setCommentType("降雨");
            tWeatherSynopsis3.setRoad(road);
            List<TWeatherSynopsis> tWeatherSynopses3 = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis3);


            // 判断是雅西还是其他地区
            commentRiskLevelRule.setRiskLevelRuleId(tWeatherSynopses3.get(0).getRiskRuleId());
            commentRiskLevelRule.setRiskType("11");
            List<TCommentRiskLevelRule> tCommentRiskLevelRules = commentRiskLevelRuleMapper.selectTCommentRiskLevelRuleList(commentRiskLevelRule);

            for (TCommentRiskLevelRule tCommentRiskLevelRule1 : tCommentRiskLevelRules) {

                // 判断降雨等级
                if (RainSum>Double.parseDouble(tCommentRiskLevelRule1.getMinValue()) && RainSum< Double.parseDouble(tCommentRiskLevelRule1.getMaxValue())){

                    TWeatherSynopsis tWeatherSynopsis = new TWeatherSynopsis();
                    tWeatherSynopsis.setCommentType("降雨");
                    tWeatherSynopsis.setRiskLevel(Integer.parseInt(tCommentRiskLevelRule1.getRiskLevel()));
                    tWeatherSynopsis.setRoad("YAXI");
                    List<TWeatherSynopsis> tWeatherSynopses = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis);
                    TWeatherSynopsis tWeatherSynopsis1 = tWeatherSynopses.get(0);

                    txt = tWeatherSynopsis1.getRiskDescription()+"，"+tWeatherSynopsis1.getTrafficImpact()+"，"+tWeatherSynopsis1.getProposeMeasure();
                    if (txt.contains("XX")){
                        txt = txt.replace("XX",timeStr);
                    }
                }
            }
        }
        return txt;
    }






    /**
     *  降雪 24小时概要
     * @param roadHsoIndexLasts 未来24小时数据
     * @param road 路段
     * @param valList
     * @return
     */
    private String snowSynopsis(List<THsoIndexLast> roadHsoIndexLasts, String road, List<THsoIndexLast> valList) {


        String txt = null;
        // 当前推送时间
        Date localTime = roadHsoIndexLasts.get(0).getLocalTime();

        // 获取事件 发送时间
        String timeStr;
        Long ft = valList.get(0).getFt();
        long localTimeInMillis = localTime.getTime();
        long newTimeInMillis = localTimeInMillis + (ft * 60 * 60 * 1000);
        Date evenStartTime = new Date(newTimeInMillis);
        int hours = evenStartTime.getHours();
        String[] timeMappings = {"下半夜", "早晨", "上午", "中午", "下午", "傍晚", "上半夜"};
        // 映射小时范围到对应的时间字符串
        int index = (hours / 3) % 8;
        timeStr = timeMappings[index];


        // 未来1天下雪总和
        double RainSum = roadHsoIndexLasts.stream().mapToDouble(hsoIndexAll -> Double.parseDouble(hsoIndexAll.getSnow())).sum();

        // 降雨规则
        TCommentRiskLevelRule commentRiskLevelRule = new TCommentRiskLevelRule();
        // 判断是雅西还是其他地区
        if (road.contains("YAXI")){
            commentRiskLevelRule.setRiskLevelRuleId("YAXI");
        }else {
            commentRiskLevelRule.setRiskLevelRuleId("standard");
        }
        commentRiskLevelRule.setRiskType("11");
        List<TCommentRiskLevelRule> tCommentRiskLevelRules = commentRiskLevelRuleMapper.selectTCommentRiskLevelRuleList(commentRiskLevelRule);

        for (TCommentRiskLevelRule tCommentRiskLevelRule : tCommentRiskLevelRules) {

            // 判断降雨等级
            if (RainSum>Double.parseDouble(tCommentRiskLevelRule.getMinValue()) && RainSum< Double.parseDouble(tCommentRiskLevelRule.getMaxValue())){

                TWeatherSynopsis tWeatherSynopsis = new TWeatherSynopsis();
                tWeatherSynopsis.setCommentType("降雨");
                tWeatherSynopsis.setRiskLevel(Integer.parseInt(tCommentRiskLevelRule.getRiskLevel()));
                List<TWeatherSynopsis> tWeatherSynopses = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis);
                TWeatherSynopsis tWeatherSynopsis1 = tWeatherSynopses.get(0);

                txt = tWeatherSynopsis1.getRiskDescription()+tWeatherSynopsis1.getTrafficImpact()+tWeatherSynopsis1.getProposeMeasure();
                if (txt.contains("XX")){
                    txt = txt.replace("XX",timeStr);
                }
            }

        }
        return txt;
    }






    /**
     * 未来3天 气象 拼接
     * @param roadHsoIndexLasts
     * @return
     */
    private String futureWeatherSynopsis(List<THsoIndexLast> roadHsoIndexLasts){


        // 未来24小时气象概要
        StringBuilder predictionComment = new StringBuilder();

        // 1.季节
        String season = null;
        LocalDateTime now = LocalDateTime.now();
        int monthValue = now.getMonthValue();
        List<TSeason> tSeasons = tSeasonMapper.selectTSeasonList(new TSeason());


        // 判断当前月份
        for (TSeason tSeason : tSeasons) {

            // 暖侯期
            if (tSeason.getName().contains("冰")){

                if (monthValue>=tSeason.getMonthMin() || monthValue<=tSeason.getMonthMax()){
                    season = tSeason.getName();
                    break;
                }

                // 冰雪期
            }else {

                if (monthValue>=tSeason.getMonthMin() && monthValue<=tSeason.getMonthMax()){
                    season = tSeason.getName();
                    break;
                }
            }
        }


        // 提取事件
        List<THsoIndexLast> valList = new ArrayList<>();

        String txt = null;

        int a = 0;
        assert season != null;
        if (season.equals("暖侯期")){

            // 降雨判断
            for (THsoIndexLast hsoIndexLast : roadHsoIndexLasts) {

                LocalDateTime localDateTime = hsoIndexLast.getLocalTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                // 将当前时间加上一天，并设置时间为0点
                LocalDateTime nextDayMidnight = localDateTime.plusDays(1).with(LocalTime.MIDNIGHT);
                Duration duration = Duration.between(localDateTime, nextDayMidnight);
                long ftNextDay = duration.toHours();


                if (hsoIndexLast.getFt()< ftNextDay){
                    continue;
                }
                String rain = hsoIndexLast.getRain();
                if (rain != null && !rain.equals("0") && !rain.equals("0.0") && !rain.equals("")) {
                    valList.add(hsoIndexLast);
                    a = 1;
                } else {
                    if (a == 1) {
                        break;
                    }
                }
            }

            // 降雨
            if (valList.size()>0){

                LocalDateTime localDateTime = valList.get(0).getLocalTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
                // 将当前时间加上二天，并设置时间为0点
                LocalDateTime next2DayMidnight = localDateTime.plusDays(2).with(LocalTime.MIDNIGHT);
                Duration duration2 = Duration.between(localDateTime, next2DayMidnight);
                long ft2NextDay = duration2.toHours();

                THsoIndexLast tHsoIndexLast = valList.get(0);
                if (tHsoIndexLast.getFt() < ft2NextDay){

                    txt = "预计明天会有降雨天气，请关注每日最新预报";
                }else {
                    txt = "预计后天会有降雨天气，请关注每日最新预报";
                }

                // 无降雨
            }else {

                txt = "未来三天，天气正常，预计无恶劣天气。";
            }

            // 降雪
        }else {

        }

        predictionComment.append(txt);
        return predictionComment.toString();
    }


    /**
     * 精细化预报拼接
     * @param parentId
     * @param road
     * @return
     */
    private String refinementWeatherSynopsis(Long parentId, String road){


        StringBuilder refinement = new StringBuilder();


        TPrediction tPrediction = new TPrediction();
        tPrediction.setParentId(parentId);
        List<TPrediction> tPredictions = predictionService.selectTPredictionList(tPrediction);

        DecimalFormat df = new DecimalFormat("#.#");


        // 降雪总和
        double snowSum = tPredictions.stream().mapToDouble(prediction -> { String snow = prediction.getSnow(); if (snow == null || snow.isEmpty()) { return 0.0; } else { return Double.parseDouble(snow); } }).sum();
        snowSum = Double.parseDouble(df.format(snowSum));


        // 降雨总和
        double rainSum = tPredictions.stream().mapToDouble(prediction -> { String rain = prediction.getRain(); if (rain == null || rain.isEmpty()) { return 0.0; } else { return Double.parseDouble(rain); } }).sum();
        rainSum = Double.parseDouble(df.format(rainSum));



        // 最低温度
        Optional<Double> minTmp = tPredictions.stream()
                .map(prediction -> prediction.getAirtmp())
                .filter(tmp -> tmp != null && tmp.matches("\\d+\\.\\d"))
                .map(Double::parseDouble)
                .min(Double::compareTo);

        if (minTmp.isPresent()) {
            refinement.append("最低温度: ").append(minTmp.get()).append("℃，");
        } else {
            refinement.append("最低温度: 暂无数据，");
        }



        // 降雪
        if (snowSum !=0.0){


            // 降雪量最大值
            Optional<String> snowMax = tPredictions.stream().map(TPrediction::getSnow).filter(snow -> snow != null && !snow.isEmpty()).max(Comparator.naturalOrder());
            refinement.append("降雪强度最高为:").append(snowMax.orElse("暂无数据")).append("mm/h，");
            refinement.append("未来24小时累计降雪量达:").append(snowSum).append("mm/h，");


            // 降雪规则
            TCommentRiskLevelRule commentRiskLevelRule = new TCommentRiskLevelRule();

            TWeatherSynopsis tWeatherSynopsis3 = new TWeatherSynopsis();
            tWeatherSynopsis3.setCommentType("降雪");
            tWeatherSynopsis3.setRoad(road);
            List<TWeatherSynopsis> tWeatherSynopses3 = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis3);

            // 判断是雅西还是其他地区
            commentRiskLevelRule.setRiskLevelRuleId(tWeatherSynopses3.get(0).getRiskRuleId());
            commentRiskLevelRule.setRiskType("11");
            List<TCommentRiskLevelRule> tCommentRiskLevelRules = commentRiskLevelRuleMapper.selectTCommentRiskLevelRuleList(commentRiskLevelRule);


            for (TCommentRiskLevelRule tCommentRiskLevelRule1 : tCommentRiskLevelRules) {

                // 判断降雪等级
                if (snowSum>Double.parseDouble(tCommentRiskLevelRule1.getMinValue()) && snowSum< Double.parseDouble(tCommentRiskLevelRule1.getMaxValue())){


                    refinement.append("达到").append(tCommentRiskLevelRule1.getRiskName()).append("等级，");
                    TWeatherSynopsis tWeatherSynopsis = new TWeatherSynopsis();
                    tWeatherSynopsis.setCommentType("降雪");
                    tWeatherSynopsis.setRiskLevel(Integer.parseInt(tCommentRiskLevelRule1.getRiskLevel()));
                    List<TWeatherSynopsis> tWeatherSynopses = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis);
                    TWeatherSynopsis tWeatherSynopsis1 = tWeatherSynopses.get(0);
                    refinement.append(tWeatherSynopsis1.getTrafficImpact()).append("。");
                }
            }

        }else if (rainSum !=0.0){


            // 降雨量最大值
            Optional<String> snowMax = tPredictions.stream().map(TPrediction::getRain).filter(rain -> rain != null && !rain.isEmpty()).max(Comparator.naturalOrder());
            refinement.append("降雨强度最高为").append(snowMax.orElse("暂无数据")).append("mm/h，");

            refinement.append("未来24小时累计降雨量达").append(rainSum).append("mm，");


            // 降雨规则
            TCommentRiskLevelRule commentRiskLevelRule = new TCommentRiskLevelRule();

            TWeatherSynopsis tWeatherSynopsis3 = new TWeatherSynopsis();
            tWeatherSynopsis3.setCommentType("降雨");
            tWeatherSynopsis3.setRoad(road);
            List<TWeatherSynopsis> tWeatherSynopses3 = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis3);

            // 判断是雅西还是其他地区
            commentRiskLevelRule.setRiskLevelRuleId(tWeatherSynopses3.get(0).getRiskRuleId());
            commentRiskLevelRule.setRiskType("11");
            List<TCommentRiskLevelRule> tCommentRiskLevelRules = commentRiskLevelRuleMapper.selectTCommentRiskLevelRuleList(commentRiskLevelRule);


            for (TCommentRiskLevelRule tCommentRiskLevelRule1 : tCommentRiskLevelRules) {

                // 判断降雪等级
                if (rainSum>Double.parseDouble(tCommentRiskLevelRule1.getMinValue()) && rainSum< Double.parseDouble(tCommentRiskLevelRule1.getMaxValue())){


                    refinement.append("达到").append(tCommentRiskLevelRule1.getRiskName()).append("等级，");
                    TWeatherSynopsis tWeatherSynopsis = new TWeatherSynopsis();
                    tWeatherSynopsis.setCommentType("降雨");
                    tWeatherSynopsis.setRiskLevel(Integer.parseInt(tCommentRiskLevelRule1.getRiskLevel()));
                    List<TWeatherSynopsis> tWeatherSynopses = weatherSynopsisService.selectTWeatherSynopsisList(tWeatherSynopsis);
                    TWeatherSynopsis tWeatherSynopsis1 = tWeatherSynopses.get(0);
                    refinement.append("预计").append(tWeatherSynopsis1.getTrafficImpact()).append("。");
                }
            }
        }else {

            refinement.append("预计无恶劣天气。");
        }

        return refinement.toString();
    }















}
